assume cs:code

data segment
        db 10 dup (0)
data ends

code segment
        start:mov ax, 12666
              mov bx, data
              mov ds, bx
              mov si, 0
              call dtoc

              mov dh, 8
              mov dl, 3
              mov cl, 2
              call show_str

              mov ax, 4c00h
              int 21h


        dtoc: push cx
              mov di, 10


       devide:mov dx, 0
              div di
              mov cx, ax
              add dx, 30h
              mov [si], dl
              add si, 1

              jcxz return
              jmp short devide

       return:pop cx
              mov di, 0
              mov dx, 0
              mov si, 0
              ret

 show_str: push cx 
          push si
          push dx

          mov bx, dx ;将dx的值保存起来，因为下面执行完mul bp后dx竟然置0了，不止为何？？？
            
          mov ax, 160
          mul bh    ;为什么没有将bh-1，是因为dos显示的原因，不必深究    
          mov bp, ax ;定位到要显示到屏幕的行对应的内存的首地址
          
          mov ax, 2
          mul bl 
          mov di, ax  ;定位到要显示字符串的位置在内存中的位置
          
          mov dl, cl ;因为cx要使用，故先将其中内容存下来，其内容为字符属性
          mov ax, 0B800H
          mov es, ax

    show: mov ah, dl	;将字符属性放在ax高字节中
          mov cl, ds:[si]	;字符放在cx低字节中
          mov ch, 0			;cx高字节放0
          jcxz ok
          mov al, cl	;将字符放入ax低字节，注意ax高字节放的字符属性
          mov es:[bp+di], ax
          inc si
          add di, 2
          jmp short show

      ok: pop dx
          pop si
          pop cx
          ret
code ends
end start
